﻿using ProxyViewModel.Attributes;
using ProxyViewModel;
using System.Windows.Input;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AutoViewModel.Tests {
	[TestClass]
	public class CommandsAutomaticInvalidation {
		public class AViewModel {
			private bool _canExecuteWasCalled = false;
			private int _invalidationCount = 0;

			public int InvalidationCount {
				get { return _invalidationCount; }
			}

			public bool CanExecuteWasCalled {
				get { return _canExecuteWasCalled; }
			}

			public virtual string Property1 {
				get;
				set;
			}

			public virtual decimal Property2 {
				get;
				set;
			}

			[DonotInvalidateCommands]
			public virtual int Property3 {
				get;
				set;
			}

			public void Test1Command() {

			}

			public bool CanExecuteTest1Command() {
				_canExecuteWasCalled = true;
				_invalidationCount++;
				return true;
			}
		}

		[TestMethod]
		public void TestAutomaticInvalidation() {
			AViewModel viewModel = ProxyViewModelFactory.CreateProxyViewModel<AViewModel>();

			ICommand test1Command = CommandsTesting.GetCommand(viewModel, "Test1");

			// create a listener so command so that it has CanExecute event set
			test1Command.CanExecuteChanged += (s, e) => {
				test1Command.CanExecute(null);
				};


			viewModel.Property1 = "testValue";
			viewModel.Property2 = 123;


			Assert.IsTrue(viewModel.CanExecuteWasCalled, "CanExecuteTest1Command must be called");
			Assert.AreEqual(2, viewModel.InvalidationCount, "CanExecuteTest1Command must be called 2 times");
		}

		[TestMethod]
		public void TestAutomaticInvalidationAndIgnoreInvalidation() {
			AViewModel viewModel = ProxyViewModelFactory.CreateProxyViewModel<AViewModel>();

			ICommand test1Command = CommandsTesting.GetCommand(viewModel, "Test1");

			// create a listener so command so that it has CanExecute event set
			test1Command.CanExecuteChanged += (s, e) => {
				test1Command.CanExecute(null);
			};


			viewModel.Property1 = "testValue";
			viewModel.Property2 = 123;
			// this property set should never call command invalidation
			viewModel.Property3 = 23423;


			Assert.IsTrue(viewModel.CanExecuteWasCalled, "CanExecuteTest1Command must be called");
			Assert.AreEqual(2, viewModel.InvalidationCount, "CanExecuteTest1Command must be called 2 times");
		}
	}
}
